package com.ayf.payment.game.api.controller.paychannel;

import com.alibaba.fastjson.JSONObject;
import com.ayf.payment.game.api.channel.jiabei.util.JbStringUtil;
import com.ayf.payment.game.api.dto.platform.PaymentChannelDTO;
import com.ayf.payment.game.api.entity.Order;
import com.ayf.payment.game.api.type.OrderStatus;
import com.ayf.payment.game.api.utils.Md5Utils;
import com.ayf.payment.game.api.utils.SnowFlakeUtils;
import com.ayf.payment.game.api.wx.WxSendMsgUtils;
import com.swwx.charm.commons.lang.utils.LogPortal;
import com.swwx.charm.zookeeper.exception.GetLockFailedException;
import com.swwx.charm.zookeeper.exception.ReleaseLockFailedException;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 支付云
 * @author wwl
 * @description:
 * @date 2020/5/18 20:15
 */
@RequestMapping("/v/zfy/pay")
@RestController
public class ZFYPayNotifyController extends BasePayNotifyController {
    @Autowired
    private WxSendMsgUtils wxSendMsgUtils;
    /**
     * 异步通知处理
     */
    @RequestMapping("/notify")
    public void notify(HttpServletRequest request, HttpServletResponse response) {
        String orderNo = JbStringUtil.formatString(request.getParameter("OrderNo"));
        super.notifyAsync(request,response,orderNo);
    }

    /**
     * 同步通知处理
     */
    @RequestMapping("/returns")
    public void returns(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String orderNo = JbStringUtil.formatString(request.getParameter("OrderNo"));
        super.notifySync(request,response,orderNo);
    }

    @Override
    protected void notifyAsyncBusinesExec(HttpServletRequest request, HttpServletResponse response,Object obj) {
        PrintWriter pw = null;
        String traceId = SnowFlakeUtils.getTraceId();
        //获取参数
        String Version = "1.0";                                         // 版本号,默认属性值为: 1.0
        String MerId = JbStringUtil.formatString(request.getParameter("MerId"));          //由支付云统一分配的7位正整数号
        String TransNo = JbStringUtil.formatString(request.getParameter("TransNo"));      // 支付云系统的交易号
        String OrderNo = JbStringUtil.formatString(request.getParameter("OrderNo"));       // 商户订单号,50个字符内、只允许使用数字、字母,确保在商户系统唯一
        String OrderAmount = JbStringUtil.formatString(request.getParameter("OrderAmount"));      // 支付金额,必须大于0,包含2位小数如：OrderAmount=1.00
        String TransAmount = JbStringUtil.formatString(request.getParameter("TransAmount"));    //用户实际支付金额，商户以该金额为准
        String Status = JbStringUtil.formatString(request.getParameter("Status"));      // 固定值 “1”, 代表支付成功
        String TransTime = JbStringUtil.formatString(request.getParameter("TransTime"));        // 用户通过商户网站完成交易订单的时间,必须为14位正整数数字,格式为:yyyyMMddHHmmss,如:20110707112233
        String Remark = JbStringUtil.formatString(request.getParameter("Remark"));      // 英文或中文字符串支付完成后，按照原样返回给商户
        String Sign = JbStringUtil.formatString(request.getParameter("Sign"));          // 签名数据
        LogPortal.info("支付云交易异步通知 参数：Version={}MerId={}TransNo={}OrderNo={}OrderAmount={}TransAmount={}Status={}TransTime={}Remark={}",Version,MerId,TransNo,OrderNo,OrderAmount,TransAmount,Status,TransTime,Remark);
        try {
            pw = response.getWriter();
            if (StringUtils.isEmpty(OrderNo)) {
                LogPortal.info("{} 支付云交易异步通知 商户订单号数值为空，不进行后续操作", traceId);
                pw.write("ERROR订单未支付成功");
                pw.flush();
                return;
            }
            Order order = orderService.selectByMerchantOrderNo(OrderNo);
            if (order == null) {
                LogPortal.error("{} 支付云交易异步通知 订单号[{}]在我方系统查询不到", traceId, OrderNo);
                pw.write("ERROR订单未支付成功");
                pw.flush();
                return;
            }
            PaymentChannelDTO paymentChannelDTO = systemInitialization.channelDTO(order.getPayChannleId());
            //商户编号
            String MerhantId = paymentChannelDTO.getAccountNumber();
            //测试商户密钥
            String KeyValue = paymentChannelDTO.getChannelKey();
            String Origin=Version+MerId+TransNo+OrderNo+OrderAmount+TransAmount+Status+TransTime+Remark;
            String signVer = Md5Utils.encryption(Origin + "|" + KeyValue);
            LogPortal.info("支付云 {} 验签组成数据： {} signVER: {}--{}", traceId,Origin , signVer, Sign);
            if (Sign.trim().equals(signVer.trim())) {
                if ("1".equals(Status)) {
                    if (OrderStatus.PROCESSING.equals(order.getOrderStatus())) {
                        String XY_GAME_PAY_LOCK_FLAG= System.getenv("XY_GAME_PAY_LOCK_FLAG");
                        String orderLockName = "orderLock".concat(this.getClass().getSimpleName()).concat(XY_GAME_PAY_LOCK_FLAG).concat(OrderNo);
                        boolean orderLock=false;
                        try {
                            if (orderLock = distributedLock.getLock(orderLockName)) {
                                Order order2 = orderService.selectByMerchantOrderNo(OrderNo);
                                if (order2 != null && OrderStatus.PROCESSING.equals(order2.getOrderStatus())){
                                    order.setOrderNo(TransNo);
                                    order.setOrderStatus(OrderStatus.SUCCESS);
                                    orderService.paymentOrder(order, new JSONObject());
                                    if (OrderStatus.SUCCESS.equals(order.getOrderStatus())) {
                                        orderService.orderToGetWay(order);
                                        try {
                                            wxSendMsgUtils.rechargeSuccess(order);
                                        } catch (Exception e) {
                                            LogPortal.error("{} 支付云交易异步通知 商户订单号[{}]CallBack 微信通知异常", e, traceId, OrderNo);
                                        }
                                    }
                                }
                            }
                        } catch (GetLockFailedException e) {
                            LogPortal.error("{} >>> [DISTRIBUTED_LOCK_ACQUIRE_FAILED_ZK] 分布式锁获取失败,锁名称为:{}", OrderNo, orderLockName);
                            LogPortal.error("{} >>> {} 获取lock失败", e, OrderNo, orderLockName);
                        } catch (Exception e) {
                            LogPortal.error("{} >>> {} 任务执行出错 ", e, OrderNo, orderLockName);
                        } finally {
                            if (orderLock) {
                                LogPortal.info(OrderNo + " >>> " + orderLockName + " finished.");
                                try {
                                    distributedLock.releaseLock(orderLockName);
                                } catch (ReleaseLockFailedException e) {
                                    LogPortal.error("{} >>> [DISTRIBUTED_LOCK_RELEASE_FAILED_ZK] 分布式锁释放失败,锁名称为:{}",OrderNo, orderLockName);
                                    LogPortal.error("{} >>> {} 释放失败", e, OrderNo, orderLockName);
                                }
                            }
                        }
                    }else{
                        LogPortal.info("{} 支付云交易异步通知 商户订单号[{}] 异步通知 不在更新订单状态：[{}]", traceId, OrderNo,order.getOrderStatus());
                    }
                } else {
                    order.setOrderNo(TransNo);
                    order.setOrderStatus(OrderStatus.FAIL);
                    orderService.paymentOrder(order, new JSONObject());
                }
            } else {
                LogPortal.error("{} 支付云交易异步通知 商户订单号[{}] 异步通知验签失败", traceId, OrderNo);
            }
        } catch (Exception e) {
            LogPortal.error("{} 支付云交易异步通知 验签业务逻辑处理失败 订单号:[{}]，具体原因:{}", e, traceId,OrderNo, e.getMessage());
        } finally {
            pw.write("OK");
            pw.flush();
            if (pw != null)
                pw.close();
        }
    }

    @Override
    protected void notifySyncBusinesExec(HttpServletRequest request, HttpServletResponse response) {
        String orderno = JbStringUtil.formatString(request.getParameter("OrderNo"));
        try {
            String attach = JbStringUtil.formatString(request.getParameter("Remark"));
            response.sendRedirect(attach + "/gws/loading.html?orderNo=" + orderno);
        } catch (Exception e) {
            LogPortal.error("订单号:{} 支付云交易同步通知 发生{}异常",e,orderno,e.getClass().getName());
        }
    }

    @Override
    protected void agentPayNotifyAsyncBusinesExec(HttpServletRequest request, HttpServletResponse response, Object obj) {

    }
}
